package com.lyl.syt.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyl.syt.common.exception.YyghException;
import com.lyl.syt.common.helper.JwtHelper;
import com.lyl.syt.common.result.ResultCodeEnum;
import com.lyl.syt.dao.UserInfoDao;
import com.lyl.syt.enums.AuthStatusEnum;
import com.lyl.syt.model.user.UserInfo;
import com.lyl.syt.service.PatientService;
import com.lyl.syt.service.UserInfoService;
import com.lyl.syt.vo.user.LoginVo;
import com.lyl.syt.vo.user.UserAuthVo;
import com.lyl.syt.vo.user.UserInfoQueryVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class UserInfoServiceImpl extends ServiceImpl<UserInfoDao, UserInfo> implements UserInfoService {
    private final PatientService patientService;

    //用户登录接口
    @Override
    public Map<String, Object> loginUser(LoginVo loginVo) {
        //从loginVo中获取输入的手机号和验证码
        String phone = loginVo.getPhone();
        String code = loginVo.getCode();
        //判断手机号和验证码是否为空
        if (StrUtil.isBlank(phone) || StrUtil.isBlank(code)) {
            throw new YyghException(ResultCodeEnum.PARAM_ERROR);
        }

        //绑定手机号码
        UserInfo userInfo = null;
        if (StrUtil.isNotBlank(loginVo.getOpenid())) {
            userInfo = lambdaQuery().eq(UserInfo::getOpenid, loginVo.getOpenid()).one();
            if (userInfo != null) {
                userInfo.setPhone(loginVo.getPhone());
                this.updateById(userInfo);
            } else {
                throw new YyghException(ResultCodeEnum.DATA_ERROR);
            }
        }

        if (userInfo == null) {
            //判断是否是第一次登录，根据手机号查询数据库，如果不存在相同的手机号则是第一次登录
            userInfo = lambdaQuery().eq(UserInfo::getPhone, phone).one();
            if (userInfo == null) {
                //表示当前第一次使用这个手机号登录
                userInfo = new UserInfo();
                userInfo.setName("");
                userInfo.setPhone(phone);
                userInfo.setStatus(1);
                save(userInfo);
            }
        }

        //判断用户是否禁用
        if (userInfo.getStatus() == 0) {
            throw new YyghException(ResultCodeEnum.LOGIN_DISABLED_ERROR);
        }
        //不是第一次登录，直接登录

        //返回登录信息、返回登录用户名、返回token
        Map<String, Object> map = new HashMap<>();
        String name = userInfo.getName();
        name = StrUtil.isBlank(name) ? userInfo.getNickName() : name;
        name = StrUtil.isBlank(name) ? userInfo.getPhone() : name;
        map.put("name", name);

        // jwt 生成token
        String token = JwtHelper.createToken(userInfo.getId(), name);
        map.put("token", token);
        return map;
    }

    @Override
    public void userAuth(Long userId, UserAuthVo authVo) {
        //根据用户id查询用户信息
        UserInfo userInfo = getById(userId);
        //设置认证信息
        BeanUtil.copyProperties(authVo, userInfo);
        //设置状态
        userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());
        //更新用户信息
        saveOrUpdate(userInfo);
    }

    @Override
    public IPage<UserInfo> selectPage(Page<UserInfo> pageParam, UserInfoQueryVo queryVo) {
        String name = queryVo.getKeyword();
        Integer status = queryVo.getStatus();
        Integer authStatus = queryVo.getAuthStatus();
        String createTimeBegin = queryVo.getCreateTimeBegin();
        String createTimeEnd = queryVo.getCreateTimeEnd();

        Page<UserInfo> page = lambdaQuery()
                .like(StrUtil.isNotBlank(name), UserInfo::getName, name)
                .eq(ObjectUtil.isNotNull(status), UserInfo::getStatus, status)
                .eq(ObjectUtil.isNotNull(authStatus), UserInfo::getAuthStatus, authStatus)
                .gt(StrUtil.isNotBlank(createTimeBegin), UserInfo::getCreateTime, createTimeBegin)
                .lt(StrUtil.isNotBlank(createTimeEnd), UserInfo::getCreateTime, createTimeEnd)
                .page(pageParam);

        page.getRecords().forEach(this::packageUserInfo);

        return page;
    }

    @Override
    public boolean lock(Long userId, Integer status) {
        boolean update = Arrays.asList(0, 1).contains(status);
        if (!update){
            return true;
        }
        return lambdaUpdate()
                .eq(UserInfo::getId, userId)
                .set(UserInfo::getStatus, status)
                .update();
    }

    @Override
    public Map<String, Object> show(Long userId) {
        Map<String, Object> map = new HashMap<>();
        map.put("userInfo", packageUserInfo(getById(userId)));
        map.put("patientList", patientService.findAllByUserId(userId));
        return map;
    }

    @Override
    public void approval(Long userId, Integer authStatus) {
        boolean auth = Arrays.asList(0, 1).contains(authStatus);
        if (auth) {
            lambdaUpdate()
                    .eq(UserInfo::getId, userId)
                    .set(UserInfo::getAuthStatus, authStatus)
                    .update();
        }
    }

    private UserInfo packageUserInfo(UserInfo userInfo) {
        //处理认证状态
        userInfo.getParam().put("authStatusString", AuthStatusEnum.getStatusNameByStatus(userInfo.getAuthStatus()));
        String statusString = userInfo.getStatus() == 0 ? "锁定" : "正常";
        userInfo.getParam().put("statusString", statusString);
        return userInfo;
    }
}
